package vue;

import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import modele.Plateau;
import modele.case_.Case;

/**
 * Représente la Caméra qui permet de déplacer la vue sur l'aire de jeu
 *
 * @author gervaila
 */
public class Camera {

	private Point centre;
	private Point dimensions;
	private Point centreMin;
	private Point centreMax;
	private boolean freeze;

	/**
	 * Crée un nouvelle caméra aux dimensions 'dimensions'
	 *
	 * @param dimensions les dimensions de la caméra
	 * @param tailleCarte la taille de la carte sur laquelle la caméra opère
	 */
	public Camera(Point dimensions, Point tailleCarte) {
		this.dimensions = dimensions;
		this.centreMin = new Point(dimensions.x / 2, dimensions.y / 2);
		this.centreMax = new Point(tailleCarte.x - dimensions.x / 2, tailleCarte.y - dimensions.y / 2);
		centre = new Point(dimensions.x / 2, dimensions.y / 2);
	}

	/**
	 * Redéfini le nouveau centre de la camére en fonction de 'nouveauCentre'
	 *
	 * @param nouveauCentre
	 */
	public void setCentre(Point nouveauCentre) {
		if (!freeze) {
			centre.x -= nouveauCentre.x;
			centre.y -= nouveauCentre.y;
			centre.x = Math.max(Math.min(centreMax.x, centre.x), centreMin.x);
			centre.y = Math.max(Math.min(centreMax.y, centre.y), centreMin.y);
		}
	}

	/**
	 * Détermine si la caméra bouge ou non
	 *
	 * @param freeze
	 */
	public void setFreeze(boolean freeze) {
		this.freeze = freeze;
	}

	/**
	 *
	 * @return le centre de la caméra
	 */
	public Point getCentre() {
		return centre;
	}

	/**
	 * Défini les nouvelles dimensions de la caméra
	 *
	 * @param dimensions les nouvelles dimensions
	 */
	public void setDimensions(Point dimensions) {
		this.dimensions = dimensions;
	}

	/**
	 *
	 * @return les dimensions de la caméra
	 */
	public Point getDimensions() {
		return dimensions;
	}

	/**
	 *
	 * @return le rectangle visible au travers de la caméra
	 */
	public Rectangle getRectangle() {
		return new Rectangle(centre.x - dimensions.x / 2, centre.y - dimensions.y / 2, dimensions.x, dimensions.y);
	}

	/**
	 *
	 * @param plateau le plateau de jeu
	 * @return les cases présentent dans le rectangle de la caméra
	 */
	public ArrayList<Case> getCases(Plateau plateau) {
		ArrayList<Case> cases = new ArrayList<Case>();
		Rectangle vue = getRectangle();
		int xMin = (int) vue.getX() / Plateau.TAILLE_CASE;
		int xMax = (int) (vue.getX() + vue.getWidth()) / Plateau.TAILLE_CASE;
		int yMin = (int) vue.getY() / Plateau.TAILLE_CASE;
		int yMax = (int) (vue.getY() + vue.getHeight()) / Plateau.TAILLE_CASE;
		for (int x = xMin; x <= xMax; x++) {
			for (int y = yMin; y <= yMax; y++) {
				Case c = plateau.getCase(x, y);
				if (c != null) {
					cases.add(c);
				}
			}
		}
		return cases;
	}

	/**
	 *
	 * @param c la case dont on souhaite connaitre les coordonnées
	 * @return les coordonnées en pixel de la case 'c'
	 */
	public Point getCoordonneesCase(Case c) {
		Point coin = new Point(centre.x - dimensions.x / 2, centre.y - dimensions.y / 2);
		return new Point(c.getX() * Plateau.TAILLE_CASE - coin.x, c.getY() * Plateau.TAILLE_CASE - coin.y);
	}
}
